
library ieee;
use ieee.std_logic_1164.all;
use work.mystd.all;
use ieee.std_logic_textio.all;
use std.textio.all;
use ieee.numeric_std.all;

entity Memory is
	generic (
		-- ime fajla gde su podaci za inicijalizaciju
		InitializationFileName : string := "InitFile.txt";
		-- ime fajla gde su ocekivani podaci
		ExpectedDataFileName : string := "ExpectedData.txt"
	);
	
    port (
    	clk			: in std_logic;		-- signal takta
    	ABUS		: in bus32;			-- adresna magistrala
    	DBUS		: inout	bus32;		-- magistrala podataka
    	RDBUS		: in std_logic;		-- citanje iz memorije
    	WRBUS		: in std_logic;		-- upis u memoriju
    	
    	testRequest	: in std_logic;		-- zahteva se testiranje memorije sa podacima
    									-- iz fajla koji je zadat za poredjenje
    	testAck		: out std_logic		-- odgovor na testRequest (0 - false, 1 - true)
    ); 
     
end Memory;     
        

architecture Memory of Memory is
	type memArray is array (0 to (2**10 - 1)) of bus32;
	signal data : memArray;
	
begin
	
	write: process is
 		file initFile : text open read_mode is InitializationFileName;
		variable fileLine : line;
		variable address : bus32;
		variable word : bus32;
		variable readOK1, readOK2 : boolean;
		variable first : boolean := true;
	begin
		if (first) then
			readingFile : while not endfile(initFile) loop
    			readline(initFile, fileLine);
    			hread(fileLine, address, readOK1);
    			read(fileLine, word, readOK2);
        			
    			if (readOK1 = false or readOK2 = false) then
    				ASSERT false
    				REPORT "Greska u inicijalizaciji: Linija " & fileLine.all
    				SEVERITY FAILURE;
    				exit readingFile;
    			end if;
        		
    			data(to_integer(unsigned(address))) <= bus32(unsigned(word));
			end loop readingFile;
			first := false;
		end if;
	    
		wait until clk = '1';
		if (WRBUS = '1') then
			data(to_integer(unsigned(ABUS))) <= DBUS;
		end if;
	end process write;


	readp: process is
	begin
		wait until clk = '1';
		if (RDBUS = '1') then
			DBUS <= data(to_integer(unsigned(ABUS)));
		else
			DBUS <= (others => 'Z');
		end if;
	end process readp;

	
	test: process (testRequest) is
		file expFile : text open read_mode is ExpectedDataFileName;
		variable fileLine : std.textio.line;
		variable address : bus32;
		variable wordFile, wordMem : bus32;
		variable readOK1, readOK2 : boolean;
		variable testSuccess : boolean := true;
	begin
		--wait until testRequest = '1';
		if (testRequest = '0') then
			testAck <= '0';
		elsif (testRequest = '1') then
		
		readingFile : while not endfile(expFile) loop
			readline(expFile, fileLine);
			hread(fileLine, address, readOK1);
			read(fileLine, wordFile, readOK2);
			
			if (readOK1 = false or readOK2 = false) then
				ASSERT false
				REPORT "Greska prilikom testiranja: Linija " & fileLine.all
				SEVERITY FAILURE;
				testSuccess := false;
				exit readingFile;
			end if;
			
			--wordMem := data(address);
			wordMem := std_logic_vector(data(to_integer(unsigned(address))));
			if (wordFile /= wordMem) then
				testSuccess := false;
				exit readingFile;
			end if;
		end loop readingFile;
		if (testSuccess) then
			testAck <= '1';
		else
			testAck <= '0';
		end if;
		
		end if;
		
	end process test;

end Memory;








